package com.aghcampusnavigation.navi;

import android.app.Activity;
import android.content.IntentSender;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import com.aghcampusnavigation.navi.logic.MapRoutingHandler;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

import java.util.ArrayList;

public class AGHMap extends Activity implements GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener{

    GoogleMap map;
    LatLng AGHLatLng;
    MapRoutingHandler mapRoutingHandler;
    LocationClient locationClient;
    Location currentLocation;
    ConnectionDetector cd;

    DataOfBuilding destinationBuilding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aghmap);

        getActionBar().setDisplayShowHomeEnabled(false);

        map = ((MapFragment) getFragmentManager()
                .findFragmentById(R.id.map)).getMap();
        AGHLatLng = new LatLng(50.0660796,19.9162984);
        mapRoutingHandler = new MapRoutingHandler();

        if(map != null) {
            map.setMyLocationEnabled(true);
            map.moveCamera(CameraUpdateFactory.newLatLngZoom(AGHLatLng, 13));
        }

        locationClient = new LocationClient(this, this, this);

        Bundle b = getIntent().getExtras();
        destinationBuilding = null;
        if (b != null) {
            destinationBuilding = new DataOfBuilding();
            destinationBuilding.settingNumber(b.getString("name", "ERROR"));
            destinationBuilding.settingDescription(b.getString("desc", "ERROR"));
            destinationBuilding.settingLongitude(b.getFloat("longitude", 50.0f));
            destinationBuilding.settingLatitude(b.getFloat("latitude", 19.0f));
        }

    }

    @Override
    protected void onStart() {
        super.onStart();
        // Connect the client.
        locationClient.connect();
    }

    @Override
    protected void onStop() {
        // Disconnect the client.
        locationClient.disconnect();
        super.onStop();
    }

    @Override
    protected void onResume() {
        super.onResume();
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
        if(resultCode == ConnectionResult.SUCCESS) {
            Toast.makeText(this, getResources().getText(R.string.info_google_services_ok), Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, getResources().getText(R.string.info_google_services_error), Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.aghmap, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConnected(Bundle bundle) {

        // Display the connection status
        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();

        // ASyncTask to download and parse directions from Google Map Web API
        cd = new ConnectionDetector(getApplicationContext());
        boolean hasInternetConnection = cd.isConnectingToInternet();
        if (hasInternetConnection) {
            if (destinationBuilding != null) {
                new GetRoutes().execute();
            }
        } else {
            Toast.makeText(this, "Not connected to Internet.", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onDisconnected() {

        // Display the connection status
        Toast.makeText(this, "Disconnected. Please re-connect.",
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(
                        this,
                        9000);
                /*
                 * Thrown if Google Play services canceled the original
                 * PendingIntent
                 */
            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {
            /*
             * If no resolution is available, display a dialog to the
             * user with the error.
             */
            Toast.makeText(this, connectionResult.getErrorCode(),
                    Toast.LENGTH_SHORT).show();
        }
    }


    private class GetRoutes extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... arg0) {
            currentLocation = locationClient.getLastLocation();
            String currentLatLngStr = currentLocation.getLatitude() + "," + currentLocation.getLongitude();
            String destination = destinationBuilding.gettingLongitude() + "," + destinationBuilding.gettingLatitude();
            Log.d("destinationBuilding coordinates", destination);
            mapRoutingHandler.downloadAndParse(currentLatLngStr, destination);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            if (mapRoutingHandler.isParsingStatusOK()) {
                int duration = mapRoutingHandler.getDuration();
                String durationStr = String.format("%d:%02d", duration/60, duration%60);
                TextView durationText = (TextView) findViewById(R.id.durationText);
                durationText.setText(durationStr + " min");

                float distance = (float)mapRoutingHandler.getDistance() / 1000.0f;
                String distanceStr = String.format("%.2f", distance);
                TextView distanceText = (TextView) findViewById(R.id.distanceText);
                distanceText.setText(distanceStr + " km");


                ArrayList<LatLng> routingPoints = mapRoutingHandler.getDetailedPoints();
                try {
                    map.addPolyline(new PolylineOptions()
                            .addAll(routingPoints)
                            .color(0xff77aaff)
                            .width(5)
                            .geodesic(true)
                            .zIndex(1));
                    map.addCircle(new CircleOptions()
                            .center(routingPoints.get(0))
                            .radius(2)
                            .fillColor(0xffe0e0e0)
                            .strokeWidth(3)
                            .zIndex(2));
                    map.addCircle(new CircleOptions()
                            .center(routingPoints.get(routingPoints.size() - 1))
                            .radius(2)
                            .fillColor(0xffe0e0e0)
                            .strokeWidth(3)
                            .zIndex(2));
                    map.addMarker(new MarkerOptions()
                            .title(destinationBuilding.gettingNumber())
                            .snippet(destinationBuilding.gettingDescription())
                            .position(routingPoints.get(routingPoints.size() - 1)));
                } catch (Exception e) {
                    Log.e(getClass().getSimpleName(), "exception addPolyline: " + e.getMessage());
                }
            }
        }
    }
}
